`timescale 1ns / 1ps

/*
@20240919:针对拼接相机调试阶段的实际需求进行改造,原来的CCD驱动模块视为LM98725芯片.
*/

module mosaic_tb();

//  系统时钟@1000MHz,在激励信号部分生成
reg clk_sys;
reg ccd_drv_trig;

///////////////////////////////////////////////////////////////////////////////
//  垂直转移驱动参数
// parameter ccd_I1_A = 32'd150;
// parameter ccd_I1_B = 32'd250;
// parameter ccd_I2_A = 32'd100;
// parameter ccd_I2_B = 32'd200;
// parameter ccd_I3_A = 32'd150;
// parameter ccd_I3_B = 32'd250;
// parameter ccd_I4_A = 32'd100;
// parameter ccd_I4_B = 32'd200;

// parameter ccd_I1_A = 32'd15;
// parameter ccd_I1_B = 32'd25;
// parameter ccd_I2_A = 32'd10;
// parameter ccd_I2_B = 32'd20;
// parameter ccd_I3_A = 32'd15;
// parameter ccd_I3_B = 32'd25;
// parameter ccd_I4_A = 32'd10;
// parameter ccd_I4_B = 32'd20;

parameter ccd_I1_A = 32'd7;
parameter ccd_I1_B = 32'd12;
parameter ccd_I2_A = 32'd4;
parameter ccd_I2_B = 32'd9;
parameter ccd_I3_A = 32'd7;
parameter ccd_I3_B = 32'd12;
parameter ccd_I4_A = 32'd4;
parameter ccd_I4_B = 32'd9;

//  水平转移驱动参数
parameter ccd_phi1_A = 32'd120;
parameter ccd_phi1_B = 32'd225;
parameter ccd_phi2_A = 32'd25;
parameter ccd_phi2_B = 32'd220;
parameter ccd_phi3_A = 32'd20;
parameter ccd_phi3_B = 32'd125;
parameter ccd_rst_A  = 32'd0;
parameter ccd_rst_B  = 32'd40;

///////////////////////////////////////////////////////////////////////////////


//  wire信号
wire clk_v_1M;
wire clk_adc_50M;
wire clk_h_250M;
wire clk_reg;       // 1MHz
wire clk_reg_half;  // 0.5MHz

wire ccd_I1, ccd_I2, ccd_I3, ccd_I4;
wire ccd_phi1, ccd_phi2, ccd_phi3, ccd_rst;
wire status_htrans, status_vtrans;

wire SH_R;
wire reg_data_rdy;
wire[31:0] ddr_addr;
// wire[15:0] vtrans_cnt_dbg;
// wire[15:0] htrans_cnt_dbg;

parameter vtrans_num = 16'd5;
parameter htrans_num = 16'd10;

///////////////////////////////////////////////////////////////////////////////

//  时钟模块例化

// clk_adc_50M
clk_div #(
    .DIV_FACTOR(20),
    .CNT_START(0)
    )
    i_clk_div_adc(
        .clk_sys(clk_sys),
        .clk_div(clk_adc_50M)     // 1000MHz / 20 = 50MHz
    );

//  clk_v_1M
clk_div #(
    .DIV_FACTOR(1000),
    .CNT_START(0)
    )
    i_clk_div_v(
        .clk_sys(clk_sys),
        .clk_div(clk_v_1M)     // 1000MHz / 1000 = 1MHz
    );

//  clk_h_250M
clk_div #(
    .DIV_FACTOR(4),
    .CNT_START(0)
    )
    i_clk_div_h(
        .clk_sys(clk_sys),
        .clk_div(clk_h_250M)     // 1000MHz / 4 = 250MHz
    );

assign clk_reg = clk_v_1M;

clk_div #(
    .DIV_FACTOR(2000),
    .CNT_START(0)
    )
    i_clk_div_reg_half(
        .clk_sys(clk_sys),
        .clk_div(clk_reg_half)     // 1000MHz / 1000 = 1MHz
    );


//  驱动模块例化
LM98725 i_lm98725(
    .clk_v(clk_v_1M),    // Clock
    .clk_h(clk_h_250M),
    .clk_reg(clk_reg),
    .clk_reg_half(clk_reg_half),
    .ccd_drv_trig(SH_R),  // Asynchronous reset active low

//    .vtrans_num(16'd1),
    .htrans_num(htrans_num),

    .ccd_I1_A(ccd_I1_A),
    .ccd_I1_B(ccd_I1_B),
    .ccd_I2_A(ccd_I2_A),
    .ccd_I2_B(ccd_I2_B),
    .ccd_I3_A(ccd_I3_A),
    .ccd_I3_B(ccd_I3_B),
    .ccd_I4_A(ccd_I4_A),
    .ccd_I4_B(ccd_I4_B),
    // .ccd_Ix_MAX(32'd300),
    .ccd_Ix_MAX(32'd30),

    .ccd_phi1_A(ccd_phi1_A),
    .ccd_phi1_B(ccd_phi1_B),
    .ccd_phi2_A(ccd_phi2_A),
    .ccd_phi2_B(ccd_phi2_B),
    .ccd_phi3_A(ccd_phi3_A),
    .ccd_phi3_B(ccd_phi3_B),
    .ccd_rst_A(ccd_rst_A),
    .ccd_rst_B(ccd_rst_B),
    
    .ccd_I1(ccd_I1),
    .ccd_I2(ccd_I2),
    .ccd_I3(ccd_I3),
    .ccd_I4(ccd_I4),

    .ccd_phi1(ccd_phi1),
    .ccd_phi2(ccd_phi2),
    .ccd_phi3(ccd_phi3),
    .ccd_rst(ccd_rst),

    .status_htrans(status_htrans),
    .status_vtrans(status_vtrans)
);

MOSAIC_CCD u_mosaic_ccd(
    .trigger(ccd_drv_trig),
    .ADC_CLK(clk_adc_50M),
    .clk_reg(clk_v_1M),
    .vtrans_num(vtrans_num),
    .htrans_num(htrans_num),
    .R2(ccd_phi2),
    .SH_R(SH_R),
    .reg_data_rdy(reg_data_rdy),
    .ddr_addr(ddr_addr)
);



//  ==== 仿真 ====
//  激励信号

//reg[31:0] clk_cnt;

initial begin
   clk_sys = 0;
   forever begin
       #1 clk_sys = ~clk_sys;
   end 
end

//  dump wave settings
initial begin
    $dumpfile("wave.vcd");
    $dumpvars(0,mosaic_tb);
end

//  设置驱动触发信号
initial begin
    ccd_drv_trig = 0;
    #10000 ccd_drv_trig = 1;
    #5000 ccd_drv_trig = 0;
end

//  设置仿真停止时间

initial begin
//     #200000;
    #430000;
    $finish;
end

endmodule

